package com.feiwo.nonego.rpc.proxy.asm.proxy;

import com.feiwo.nonego.rpc.proxy.asm.classloader.AsmClassLoader;
import com.feiwo.nonego.rpc.proxy.asm.factory.AsmGenProxyFactory;

import java.lang.reflect.InvocationHandler;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *
 *
 * @author feiwo 2025-08-15
 */
public class AsmProxy {

    protected InvocationHandler handler;

    private static final AtomicInteger PROXY_COUNT = new AtomicInteger(0);
    private static final String PROXY_CLASS_NAME_PRE = "$proxy";

    public AsmProxy(InvocationHandler handler) {
        this.handler = handler;
    }

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) throws Exception{
        var proxyClass = gen(interfaces);
        var constructor = proxyClass.getConstructor(InvocationHandler.class);
        return constructor.newInstance(handler);
    }

    private static Class<?> gen(Class<?>[] interfaces) throws ClassNotFoundException {
        var proxyClassName = PROXY_CLASS_NAME_PRE + PROXY_COUNT.getAndIncrement();
        var codes = AsmGenProxyFactory.generateClass(interfaces, proxyClassName);
        var asmClassLoader = new AsmClassLoader();
        asmClassLoader.addClass(proxyClassName, codes);
        return asmClassLoader.loadClass(proxyClassName);
    }
}
